#include "database/connection.h"
#include "database/database.h"
#include "settings/settings.h"

namespace Tvimeg
{
	enum DatabaseVersion
	{
		DV_ADDED_TV_NEEDS_UPDATE_FIELD = 7,

		DV_NEXT_VERSION,
		DV_CURRENT_VERSION = DV_NEXT_VERSION - 1
	};

	Database::Database(void)
		:	connection(NULL)
	{
	}

	Database::~Database(void)
	{
		delete connection;
	}

	void Database::Initialise(void)
	{
		// get the database file from the settings
		databaseFile = Settings::GetInstance().GetDatabaseFile();

		// connect to the database
		delete connection;
		connection = new Connection(databaseFile);

		// get the version number from the database
		const DatabaseVersion version = static_cast< DatabaseVersion >( connection->GetInt("SELECT value FROM settings WHERE name = 'version';", 0) );

		// database version number is invalid, so just recreate it
		if (version != DV_CURRENT_VERSION)
		{
			CreateDatabase(*connection);
		}
	}

	void Database::CreateDatabase(Connection& connection)
	{
		// create the settings table and insert the current version number
		connection.ExecuteQuery("DROP TABLE IF EXISTS settings;");
		connection.ExecuteQuery("CREATE TABLE settings (name TEXT PRIMARY KEY, value INTEGER);");
		connection.PrepareQuery("INSERT INTO settings VALUES ('version', ?1)");
		connection.BindInt(1, DV_CURRENT_VERSION);
		connection.ExecuteQuery();

		// create the movies table
		connection.ExecuteQuery("DROP TABLE IF EXISTS movies;");
		connection.ExecuteQuery("CREATE TABLE movies (id INTEGER PRIMARY KEY, lookupTitle TEXT);");

		// create the files table
		connection.ExecuteQuery("DROP TABLE IF EXISTS files;");
		connection.ExecuteQuery("CREATE TABLE files (id INTEGER PRIMARY KEY, path TEXT, updateDate INTEGER, containerFormat TEXT, duration INTEGER, videoFormat TEXT, width INTEGER, height INTEGER, aspectRatio REAL, frameRate REAL, audioFormat TEXT, channels INTEGER);");

		// create the movie files table
		connection.ExecuteQuery("DROP TABLE IF EXISTS movieFiles;");
		connection.ExecuteQuery("CREATE TABLE movieFiles (movieId INTEGER, fileId INTEGER, PRIMARY KEY(movieId, fileId));");

		// create the tv shows table
		connection.ExecuteQuery("DROP TABLE IF EXISTS tvShows;");
		connection.ExecuteQuery("CREATE TABLE tvShows (id INTEGER PRIMARY KEY, lookupName TEXT, needsUpdate INTEGER);");

		// create the tv seasons table
		connection.ExecuteQuery("DROP TABLE IF EXISTS tvSeasons;");
		connection.ExecuteQuery("CREATE TABLE tvSeasons (id INTEGER PRIMARY KEY, tvShow INTEGER, season INTEGER, needsUpdate INTEGER);");

		// create the tv episodes table
		connection.ExecuteQuery("DROP TABLE IF EXISTS tvEpisodes;");
		connection.ExecuteQuery("CREATE TABLE tvEpisodes (id INTEGER PRIMARY KEY, tvShow INTEGER, tvSeason INTEGER, episode INTEGER, needsUpdate INTEGER);");

		// create the tv episode files table
		connection.ExecuteQuery("DROP TABLE IF EXISTS tvEpisodeFiles;");
		connection.ExecuteQuery("CREATE TABLE tvEpisodeFiles (episodeId INTEGER, fileId INTEGER, PRIMARY KEY(episodeId, fileId));");
	}

	Connection& Database::GetConnection(void) const
	{
		return *connection;
	}
}
